package cn.lingyangwl.agile.common.feign;

import cn.lingyangwl.agile.common.core.exception.enums.GlobalErrorEnum;
import cn.lingyangwl.framework.core.response.Resp;
import cn.lingyangwl.framework.tool.core.exception.BizException;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import feign.Response;
import feign.Util;
import feign.codec.ErrorDecoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * @author shenguangyang
 */
@Slf4j
public class MyErrorDecoder implements ErrorDecoder {
    @Override
    public Exception decode(String s, Response response) {
        String body = null;
        String url = response.request().url();
        try {
            if (response.status() == HttpStatus.NOT_FOUND.value()) {
                log.error("request url [{}] not exist", url);
                return new BizException(GlobalErrorEnum.PATH_NOT_PATH);
            }
            if (response.body() != null) {
                body = Util.toString(response.body().asReader(Util.UTF_8));
                Resp<?> resp = JSONObject.parseObject(body, new TypeReference<Resp<?>>() {});
                ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                if (Objects.nonNull(requestAttributes)) {
                    HttpServletResponse servletResponse = requestAttributes.getResponse();
                    if (Objects.nonNull(servletResponse)) {
                        servletResponse.setStatus(response.status());
                    }
                }
                log.error("url: {}, resp: {}", url, body);
                return new BizException(resp.getCode(), resp.getMsg());
            }
        } catch (Exception e) {
            if (e instanceof BizException) {
                throw (BizException)e;
            }
            log.error("error: ", e);
        }
        return new BizException(GlobalErrorEnum.INVOKE_OUTSIDE_SYSTEM);
    }
}
